package com.ymatou.iapi.trading.userquery.testcase;

import java.util.Collections;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.joda.time.DateTime;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import com.google.common.collect.Lists;
import com.ymatou.iapi.synctrade.parameter.mongo.Order;
import com.ymatou.iapi.trading.userquery.parameter.GetConsultingOrderInfoReq;
import com.ymatou.iapi.trading.userquery.parameter.resp.ConsultingOrderInfo;
import com.ymatou.iapi.trading.userquery.parameter.resp.GetConsultingOrderInfoResp;
import com.ymatou.iapi.trading.userquery.service.GetConsultingOrderInfoCall;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymttest.common.order.userquery.OrderInfoBuilder;
import com.ymttest.database.mongo.OrderQueryWapper;
import com.ymttest.database.mongo.UserIndexQueryWapper;
import com.ymttest.database.mongo.config.OrderField;
import com.ymttest.database.mongo.config.UserIndexField;
import com.ymttest.utils.DataUtil;
import com.ymttest.utils.EnvSetup;

/**
 * 获取待咨询订单
 */
@TestSuite
public class Ts_GetConsultingOrderInfo {

	private static GetConsultingOrderInfoReq req;
	private static GetConsultingOrderInfoCall getConsultingOrderInfoCall;

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("获取待咨询订单");
	}

	@Before
	public void caseUp() {
		req = new GetConsultingOrderInfoReq();
		getConsultingOrderInfoCall = new GetConsultingOrderInfoCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(getConsultingOrderInfoCall.getOpurl());
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	public GetConsultingOrderInfoResp constructExpectResponse() {

		List<Criteria> criteriaList = Lists.newArrayList(Criteria
				.where(UserIndexField.USER_ID).is(req.getUserId())
				.norOperator(Criteria.where(UserIndexField.HUNTER_ID).gt(0)));

		if (req.getSellerId() > 0)
			criteriaList.add(Criteria.where(UserIndexField.SELLER_ID).is(
					req.getSellerId()));

		if (null != req.getBeginTime())
			criteriaList.add(Criteria.where(UserIndexField.ADD_TIME).gte(
					req.getBeginTime()));

		if (null != req.getEndTime())
			criteriaList.add(Criteria.where(UserIndexField.ADD_TIME).lt(
					req.getEndTime()));

		Criteria criteria = new Criteria().andOperator(criteriaList
				.toArray(new Criteria[0]));
		Query query = Query.query(criteria);

		query.with(new Sort(Sort.Direction.DESC, UserIndexField.ADD_TIME));
		query.limit(req.getOrderNum());

		List<Long> orderIdList = new UserIndexQueryWapper().queryOrderId(query,
				req.getUserId());

		if (CollectionUtils.isEmpty(orderIdList))
			return new GetConsultingOrderInfoResp();

		query = Query.query(Criteria.where(OrderField.ID).in(orderIdList));
		query.fields().include(OrderField.ID)
				.include(OrderField.TRADING_STATUS)
				.include(OrderField.MAIN_ORDER_ID)
				.include(OrderField.TOTAL_PRICE)
				.include(OrderField.PRE_DISCOUNT).include(OrderField.FREIGHT)
				.include(OrderField.YMT_PROMOTION_AMOUNT)
				.include(OrderField.SELLER_PROMOTION_AMOUNT)
				.include(OrderField.ADD_TIME)
				.include(OrderField.YMT_COUPON_AMOUNT)
				.include(OrderField.SELLER_COUPON_AMOUNT)
				.include(OrderField.PAYABLE_AMOUNT)
				.include(OrderField.PRODUCTS);

		List<Order> orderList = new OrderQueryWapper().find(query);

		Collections.sort(orderList,
				(o1, o2) -> o2.getAddTime().compareTo(o1.getAddTime()));

		List<ConsultingOrderInfo> consultingOrderInfos = Lists.newArrayList();
		orderList.forEach(order -> consultingOrderInfos.add(OrderInfoBuilder
				.buildConsultingOrderInfo(order)));

		GetConsultingOrderInfoResp resp = new GetConsultingOrderInfoResp();
		resp.setConsultingOrderInfos(consultingOrderInfos);

		return resp;
	}

	private void verify() {
		GetConsultingOrderInfoResp expectResponse = new GetConsultingOrderInfoResp();
		expectResponse = constructExpectResponse();
		GetConsultingOrderInfoResp actualResponse = getConsultingOrderInfoCall
				.getConsultingOrderInfoResp();

		List<ConsultingOrderInfo> expectList = expectResponse
				.getConsultingOrderInfos();
		List<ConsultingOrderInfo> actualList = actualResponse
				.getConsultingOrderInfos();

		if (expectList == null) {
			DataUtil.verify(null, actualList, "验证ConsultingOrderInfos == null");
		}

		for (int i = 0; i < expectList.size(); i++) {

			ConsultingOrderInfo expect = expectList.get(i);
			ConsultingOrderInfo actual = actualList.get(i);

			Logger.comment(String.format("校验订单号: %d的ConsultingOrderInfos",
					expect.getOrderId()));

			boolean isSameOrder = expect.getOrderId() == actual.getOrderId();

			if (isSameOrder) {

				DataUtil.verifyObject(expect, actual, "ConsultingOrderInfos");

				Logger.comment(String.format(
						"校验订单号: %d的ConsultingOrderInfos.Status",
						expect.getOrderId()));
				Logger.verifyEquals(expect.getOrderStatus(),
						actual.getOrderStatus(),
						"ConsultingOrderInfos.orderStatus");

				Logger.comment(String.format(
						"校验订单号: %d的ConsultingOrderInfos.orderGroupId",
						expect.getOrderId()));
				Logger.verifyEquals(expect.getOrderGroupId(),
						actual.getOrderGroupId(),
						"ConsultingOrderInfos.orderGroupId");

				Logger.comment(String.format(
						"校验订单号: %d的ConsultingOrderInfos.ymtCouponAmount",
						expect.getOrderId()));
				Logger.verifyEquals(expect.getYmtCouponAmount().stripTrailingZeros().toPlainString(),
						actual.getYmtCouponAmount().stripTrailingZeros().toPlainString(),
						"ConsultingOrderInfos.ymtCouponAmount");

				Logger.comment(String.format(
						"校验订单号: %d的ConsultingOrderInfos.sellerCouponAmount",
						expect.getOrderId()));
				Logger.verifyEquals(expect.getSellerCouponAmount().stripTrailingZeros().toPlainString(),
						actual.getSellerCouponAmount().stripTrailingZeros().toPlainString(),
						"ConsultingOrderInfos.sellerCouponAmount");

				Logger.comment(String.format(
						"校验订单号: %d的ConsultingOrderInfos.payableAmount",
						expect.getOrderId()));
				Logger.verifyEquals(expect.getPayableAmount().stripTrailingZeros().toPlainString(),
						actual.getPayableAmount().stripTrailingZeros().toPlainString(),
						"ConsultingOrderInfos.payableAmount");

				for (int j = 0; j < expect.getOrderItemInfoForConsults().size() - 1; j++) {

					Logger.comment(String
							.format("校验订单号: %d的OrderInfos.getOrderItemInfoForConsults[%d]",
									expect.getOrderId(), j));
					DataUtil.verifyObject(expect.getOrderItemInfoForConsults()
							.get(j), actual.getOrderItemInfoForConsults()
							.get(j), String
							.format("OrderInfos.Products[%d]", j));
				}
			} else {
				DataUtil.verify(expect.getOrderId(), actual.getOrderId(),
						"验证订单id");
			}
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetConsultingOrderInfo_001() {
		Logger.start(true, "获取待咨询订单,只传userid,ordernum，倒序排列,查询成功");
		try {

			int userId = Integer.valueOf(EnvSetup.getData("BuyUserId"));

			req.setUserId(userId);
			req.setOrderNum(100);

			getConsultingOrderInfoCall.setData(req);
			getConsultingOrderInfoCall.callService();

			verify();
			
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetConsultingOrderInfo_002() {
		Logger.start(true, "获取待咨询订单, 参数全传，查询成功");
		try {

			int userId = Integer.valueOf(EnvSetup.getData("BuyUserId"));
			int sellerId = Integer.valueOf(EnvSetup.getData("SellerId"));

			req.setUserId(userId);
			req.setSellerId(sellerId);
			req.setBeginTime(DateTime.now().minusDays(10).toDate());
			req.setEndTime(DateTime.now().toDate());
			req.setOrderNum(10);

			getConsultingOrderInfoCall.setData(req);
			getConsultingOrderInfoCall.callService();

			verify();
			
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetConsultingOrderInfo_009() {
		Logger.start(true, "买家用户id为null");
		try {

			getConsultingOrderInfoCall.setData(req);
			getConsultingOrderInfoCall.callService();

			DataUtil.verify(400, getConsultingOrderInfoCall.getCode(), "验证Code");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetConsultingOrderInfo_010() {
		Logger.start(true, "orderNum为null");
		try {

			req.setUserId(1);
			getConsultingOrderInfoCall.setData(req);
			getConsultingOrderInfoCall.callService();

			DataUtil.verify(400, getConsultingOrderInfoCall.getCode(), "验证Code");

			Logger.verifyEquals("100",
					getConsultingOrderInfoCall.getString("bcode"), "验证bcode");

			Logger.verifyEquals("orderNum:orderNum未提供",
					getConsultingOrderInfoCall.getMsg(), "验证msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}